package com.originskyseed.platform.job.jobhandler.pk;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;

import com.originskyseed.platform.core.job.biz.model.ReturnT;
import com.originskyseed.platform.core.job.handler.IJobHandler;
import com.originskyseed.platform.core.job.handler.annotation.JobHandler;
import com.originskyseed.platform.core.job.log.JobLogger;
import com.originskyseed.platform.pk.model.Pk;
import com.originskyseed.platform.pk.service.IPkRuleService;
import com.originskyseed.platform.pk.service.IPkService;
import com.originskyseed.platform.recruit.service.IRecruitRelateRecommendService;
import com.originskyseed.platform.user.model.Dept;
import com.originskyseed.platform.user.model.UserInfo;
import com.originskyseed.platform.user.service.IAnchorRelateLiveService;
import com.originskyseed.platform.user.service.IDeptService;
import com.originskyseed.platform.user.service.IPlayerService;
import com.originskyseed.platform.user.service.IUserInfoService;

/**
 * pk实时结果定时任务
 *
 * @Author: wlj @date: 2021/6/11
 */

@Component
@JobHandler(value = "pkResultJobHandler")
public class PkResultJobHandler extends IJobHandler {

	@DubboReference
	private IPkService pkService;

	@DubboReference
	private IPkRuleService pkRuleService;

	@DubboReference
	private IUserInfoService userInfoService;

	@DubboReference
	private IAnchorRelateLiveService anchorRelateLiveService;

	@DubboReference
	private IPlayerService playerService;

	@DubboReference
	private IRecruitRelateRecommendService recruitRelateRecommendService;

	@DubboReference
	private IDeptService deptService;


	@Override
	public ReturnT<String> execute(String tenantCode) throws Exception {
		try {
			//查询正在进行中的任务
			Map<String, Object> map = new HashMap<>();
			map.put("state", 2);//进行中
			//现在时间
			Date date = new Date();
			List<Pk> pkList = this.pkService.selectPkResultList(map, tenantCode);
			if(pkList != null && pkList.size() > 0){
				for (Pk pk : pkList) {
					if(pk.getRuleType() != null){ //pk类型
						int pkRuleType = pk.getRuleType();
						//获取各自结果
						String objUserResult = this.pkResult(pk, pk.getObjUserId(), tenantCode);
						String toUserResult = this.pkResult(pk, pk.getToUserId(), tenantCode);
						//判断PK是否到时间
						if(pk.getEndTime() != null){
							Date endTime = pk.getEndTime();
							if(date.getTime() >= endTime.getTime()){
								//pk完成
								if(pkRuleType == 1){
									long objUser = 0L;
									if(StringUtils.isNotEmpty(objUserResult)&&!objUserResult.equals("")){
										objUser = Long.valueOf(objUserResult).longValue();
									}
									long toUser = 0L;
									if(StringUtils.isNotEmpty(toUserResult)&&!toUserResult.equals("")){
										toUser = Long.valueOf(objUserResult).longValue();
									}
									if(objUser > toUser){
										pk.setResult(2);//赢
									}else if(objUser < toUser){
										pk.setResult(1);
									}else {
										pk.setResult(3);
									}
									pk.setState(3);
									String objResult = this.getDatePoor(new Date(),new Date(),objUser);
									String toResult = this.getDatePoor(new Date(),new Date(),toUser);
									this.updatePk(pk,objResult,toResult,tenantCode);
								}else if(pkRuleType == 7 || pkRuleType == 8){
									BigDecimal objUser=new BigDecimal(0);
									BigDecimal toUser=new BigDecimal(0);
									if(StringUtils.isNotEmpty(objUserResult)&&!objUserResult.equals("")){
										objUser = new BigDecimal(objUserResult);;
									}
									if(StringUtils.isNotEmpty(toUserResult)&&!toUserResult.equals("")){
										toUser = new BigDecimal(toUserResult);
									}
									if(objUser.compareTo(toUser) == 1){
										pk.setResult(2);//赢
									}else if(objUser.compareTo(toUser) == -1){
										pk.setResult(1);
									}else {
										pk.setResult(3);
									}
									pk.setState(3);
									this.updatePk(pk,objUserResult,toUserResult,tenantCode);
								}else {
									int objUser = 0;
									int toUser = 0;
									if(StringUtils.isNotEmpty(objUserResult)&&!objUserResult.equals("")){
										objUser = Integer.parseInt(objUserResult);
									}
									if(StringUtils.isNotEmpty(toUserResult)&&!toUserResult.equals("")){
										toUser = Integer.parseInt(toUserResult);
									}
									pk.setState(3);
									pk.setToUserPerformance(objUserResult);
									pk.setToUserPerformance(toUserResult);
									this.updateResult(pk,tenantCode,objUser,toUser);
								}
							}else {
								if(pkRuleType == 1){
									long objUser = 0L;
									if(StringUtils.isNotEmpty(objUserResult)&&!objUserResult.equals("")){
										objUser = Long.valueOf(objUserResult).longValue();
									}
									long toUser = 0L;
									if(StringUtils.isNotEmpty(toUserResult)&&!toUserResult.equals("")){
										toUser = Long.valueOf(objUserResult).longValue();
									}
									String objResult = this.getDatePoor(new Date(),new Date(),objUser);
									String toResult = this.getDatePoor(new Date(),new Date(),toUser);
									this.updatePk(pk,objResult,toResult,tenantCode);
								}else {
									this.updatePk(pk,objUserResult,toUserResult,tenantCode);
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			JobLogger.log("pk结果：" + getExceptionDetail(e));
			return FAIL;
		}
		return SUCCESS;
	}

	/**
	 * 修改胜负状态
	 *
	 * @param pk
	 * @param tenantCode
	 * @param objData
	 * @param toUserData
	 * @throws Exception
	 */
	private void updateResult(Pk pk, String tenantCode, Integer objData, Integer toUserData) throws Exception {
		if (objData != null && toUserData != null) {
			if (objData > toUserData) { // 赢
				pk.setResult(2);
			} else if (objData < toUserData) { // 输
				pk.setResult(1);
			} else { // 平
				pk.setResult(3);
			}
			pk.setState(3);// 已完成
			this.pkService.updateByPrimaryKeySelectiveTenantCode(pk, tenantCode);
		}
	}

	/**
	 * 更新pk
	 * @param pk
	 * @param objResult
	 * @param tenantCode
	 * @param toUserResult
	 * @throws Exception
	 */
	private void updatePk(Pk pk, String objResult, String toUserResult, String tenantCode) throws Exception {
		pk.setObjUserPerformance(objResult);
		pk.setToUserPerformance(toUserResult);
		this.pkService.updateByPrimaryKeySelectiveTenantCode(pk, tenantCode);
	}

	/**
	 * pk结果
	 *
	 * @param pk
	 * @return
	 */
	private String pkResult(Pk pk, String userId, String tenantCode) throws Exception {
		String result = "";
		SimpleDateFormat formatTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//SimpleDateFormat formatTimes = new SimpleDateFormat("yyyy-MM-dd");
		if (pk != null && pk.getRuleType() != null) {
			int type = pk.getRuleType();
			Map<String, Object> map = new HashMap();
			List<String> userList = this.selectUserList(pk,userId,tenantCode);
			List<String> LocalUserList = new ArrayList<>();//本地用户
			if(userList != null && userList.size() > 0){
				map.put("list", userList);
				map.put("startTime", formatTime.format(pk.getBeginTime()));
				map.put("endTime", formatTime.format(new Date()));
				if (type == 1) { //直播直播时长
					Long objTimes = this.anchorRelateLiveService.pkCountAnchorLiveTimeTenantCode(map,tenantCode);
					result = this.getDatePoor(new Date(), new Date(), objTimes);
				} else if (type == 2) { //主播人气值
					Integer userNum = this.playerService.pkSelectAnchorVisitsNumber(map,tenantCode);
					if(userNum == null){
						result = "0";
					}else {
						result = userNum.toString();
					}
				} else if (type == 3) { //优质用户数
					Integer userNum = this.playerService.pkSelectHighQualityUserCount(map,tenantCode);
					if(userNum == null){
						result = "0";
					}else {
						result = userNum.toString();
					}
				} else if (type == 4) { //潜力用户数
					Integer userNum = this.playerService.pkSelectPotentialUsersCount(map,tenantCode);
					if(userNum == null){
						result = "0";
					}else {
						result = userNum.toString();
					}
				} else if (type == 5) { //内荐人数
					for (String userIds : userList) {
						UserInfo userInfo = this.userInfoService.selectByOtherAccountTenantCode(userIds,tenantCode);
						if(userInfo != null && userInfo.getId() != null){
							LocalUserList.add(userInfo.getId());
						}
					}
					if(LocalUserList != null && LocalUserList.size() > 0){
						map.put("list", LocalUserList);
						Integer countRecommends = this.recruitRelateRecommendService.countRecommendsTenantCode(map,tenantCode);
						if(countRecommends == null){
							result = "0";
						}else {
							result = countRecommends.toString();
						}
					}else {
						result = "0";
					}
				} else if (type == 6) { //主播心动用户
					Integer userNum = this.playerService.pkSelectHeartbeatCount(map,tenantCode);
					if(userNum == null){
						result = "0";
					}else {
						result = userNum.toString();
					}
				} else if (type == 7) { //新用户充值金额
					map.put("isNewPlayer", 1);
					BigDecimal amountSum = this.playerService.pkSelectNewChargeAmountSum(map,tenantCode);
					if(amountSum == null){
						result = "0";
					}else {
						result = amountSum.toString();
					}
				} else if (type == 8) { //用户充值总金额
					BigDecimal amountSum = this.playerService.pkSelectNewChargeAmountSum(map,tenantCode);
					if(amountSum == null){
						result = "0";
					}else {
						result = amountSum.toString();
					}
				} else {
					throw new Exception("PK类型不存在！");
				}
			}else {
				result = "0";
			}

		}
		return result;
	}

	/**
	 * 查询组织下的部门
	 *
	 * @param code
	 * @param list
	 * @throws Exception
	 */
	private void selectSonId(String code, List<String> list, String tenantCode) throws Exception {
		List<Dept> deptList = this.deptService.selectByParentCodeTenantCode(code,tenantCode);
		if (deptList.size() == 0) {
			Dept dept = this.deptService.selectByCodeTenantCode(code,tenantCode);
			list.add(dept.getId());
			return;
		} else {
			for (Dept depts : deptList) {
				list.add(depts.getId());
				selectSonId(depts.getCode(), list, tenantCode);
			}
		}
	}

	/**
	 * 删除重复项
	 *
	 * @param list
	 * @return
	 */
	private List removeDuplicate(List list) {
		HashSet h = new HashSet(list);
		list.clear();
		list.addAll(h);
		return list;
	}

	/**
	 * 查询用户
	 *
	 * @return
	 */
	private List<String> selectUserList(Pk pk, String userId, String tenantCode) throws Exception {
		List<String> list = new ArrayList<>();
		//UserInfo user = this.userInfoMapper.selectByPrimaryKey(userId);
		if(pk != null && pk.getObjUserType() != null) {
			int type = pk.getObjUserType();
			if (type == 6 || type == 11) { // 主播或者业务员
				UserInfo user = this.userInfoService.selectByPrimaryKeyTenantCode(userId,tenantCode);
				if(user!=null&&user.getOtherAccount()!=null&&StringUtils.isNotBlank(user.getOtherAccount())) {
					list.add(user.getOtherAccount());
				}
			} else {
				List<String> deptIdList = new ArrayList<>();
				if (type == 5 || type == 10) { //小组
					deptIdList.add(userId);
				} else {
					Dept dept = this.deptService.selectByPrimaryKeyTenantCode(userId,tenantCode);
					if(dept!=null) {
						this.selectSonId(dept.getCode(), deptIdList,tenantCode);
					}
					if (deptIdList != null && deptIdList.size() > 0) {
						this.removeDuplicate(deptIdList);
						if (dept.getSourceSys() == 1) {
							list = this.userInfoService.selectAnchorOtherAccountsByDeptIdsTenantCode(deptIdList,tenantCode);
						} else {
							list = this.userInfoService.selectSalesmanIdsByDeptIdsTenantCode(deptIdList,tenantCode);
						}
					}
				}
			}
		}
		return list;
	}

	/**
	 * 距离结束时间
	 *
	 * @param endDate
	 * @param nowDate
	 * @return
	 */
	private String getDatePoor(Date endDate, Date nowDate, Long times) {
		String time = "";
		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		long ns = 1000;
		long diff = times;
		// 获得两个时间的毫秒时间差异
		if (times == 0L) {
			diff = endDate.getTime() - nowDate.getTime();
		}
		// 计算差多少天
		long day = diff / nd;
		// 计算差多少小时
		long hour = diff % nd / nh;
		// 计算差多少分钟
		long min = diff % nd % nh / nm;
		// 计算差多少秒//输出结果
		long sec = diff % nd % nh % nm / ns;
		if (day > 0) {
			if (hour > 0) {
				if (min > 0) {
					if (sec > 0) {
						time = day + "天" + hour + "小时" + min + "分" + sec + "秒";
					} else {
						time = day + "天" + hour + "小时" + min + "分";
					}
				} else {
					time = day + "天" + hour + "小时";
				}
			} else {
				time = day + "天";
			}
		} else {
			if (hour > 0) {
				if (min > 0) {
					if (sec > 0) {
						time = hour + "小时" + min + "分" + sec + "秒";
					} else {
						time = hour + "小时" + min + "分";
					}
				} else {
					time = hour + "小时";
				}
			} else {
				if (min > 0) {
					if (sec > 0) {
						time = min + "分" + sec + "秒";
					} else {
						time = min + "分";
					}
				} else {
					time = sec + "秒";
				}
			}
		}
		return time;
	}

	/**
	 * 获取异常详细信息，知道出了什么错，错在哪个类的第几行 .
	 *
	 * @param ex
	 * @return
	 */
	public static String getExceptionDetail(Exception ex) {
		String ret = null;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		PrintStream pout = new PrintStream(out);
		try {
			ex.printStackTrace(pout);
			ret = new String(out.toByteArray());
		} catch (Exception e) {
		} finally {
			try {
				pout.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}
}
